﻿using Common;
using DataBase.Models;
using Orleans;
using Orleans.Runtime;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Server.Impl
{
    /// <summary>
    /// 交管区信息集合（基础数据）
    /// </summary>
    public class AreaSetImpl : Grain, IAreaSet
    {
        private List<AreaItem> list=new List<AreaItem>();
        private readonly ApplicationDBContext db;

        public AreaSetImpl(ApplicationDBContext adb )
        {
            db = adb;
        }


        public override async Task OnActivateAsync()
        { 
            await base.OnActivateAsync();
            await 重置交管区();
        }

        public Task<long> 是否在区域内(int X, int Y)
        {
            var tmplist = list. Where(p => p.MaxX >= X && X >= p.MinX && p.MaxY >= Y && Y >= p.MinY && p.Disable==false).ToList();
            //四边形区域快速查找
            if (tmplist.Count == 0)
            {
                return Task.FromResult(0L);
            }

            PointF current = new PointF(X, Y);
            foreach (var tmp in tmplist)
            {

                if (tmp.PointList.Count > 0 &&  处于几何图形内(X,Y, tmp.PointList))
                {
                    return Task.FromResult(tmp.AreaID);
                }
            }
            return Task.FromResult(0L);
        }



        /// <summary>
        /// 从数据库中读取
        /// </summary>
        /// <returns></returns>
        public Task 重置交管区()
        {
            //从数据库中重新加载list，自己去实现

            var 主记录 = db.areaInfo.ToList();
            var 点位=db.areaDot.ToList();

            List<AreaItem> main = new List<AreaItem>();
            主记录.ForEach(area =>
            { 
                AreaItem obj = new AreaItem()
                {
                    AreaID = area.AreaID,
                    Disable = area.Disable,
                    PointList = new List<PointF>()
                };
                var sublist = 点位.Where(x => x.AreaID == area.AreaID).OrderBy(x => x.Sort).ToList();
                sublist.ForEach(sub =>
                {
                    obj.PointList.Add(new PointF(sub.X, sub.Y)); 
                }); 
                obj.MinX=sublist.Min(m=>m.X);
                obj.MinY=sublist.Min(m=>m.Y);
                obj.MaxX=sublist.Max(m=>m.X);
                obj.MaxY=sublist.Max(m=>m.Y); 
                main.Add(obj);
            });
            list= main; 
            return Task.CompletedTask;
        }


        public Task 启用禁用(long  AreaID, bool Disable)
        {
            var item = list.Find(x => x.AreaID == AreaID);
            if (item != null)
            {
                item.Disable = Disable;
            }
            return Task.CompletedTask;
        }


        /// <summary>
        /// 判断当前位置是否处于几何图形内
        /// </summary>
        /// <param name="X"></param>
        /// <param name="Y"></param>
        /// <param name="polygonPoints"></param>
        /// <returns></returns>
        bool 处于几何图形内(int X, int Y, List<PointF> polygonPoints)
        {
            int counter = 0;
            int i;
            double xinters;
            PointF p1, p2;
            int pointCount = polygonPoints.Count;
            p1 = polygonPoints[0];
            for (i = 1; i <= pointCount; i++)
            {

                p2 = polygonPoints[i % pointCount];
                if (Y > Math.Min(p1.Y, p2.Y)//校验点的Y大于线段端点的最小Y
                    && Y <= Math.Max(p1.Y, p2.Y))//校验点的Y小于线段端点的最大Y
                {
                    if (X <= Math.Max(p1.X, p2.X))//校验点的X小于等线段端点的最大X(使用校验点的左射线判断).
                    {
                        if (p1.Y != p2.Y)//线段不平行于X轴
                        {
                            xinters = (Y - p1.Y) * (p2.X - p1.X) / (p2.Y - p1.Y) + p1.X;
                            if (p1.X == p2.X || X <= xinters)
                            {
                                counter++;
                            }
                        }
                    }

                }
                p1 = p2;
            }

            if (counter % 2 == 0)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
    }




    #region 数据定义
    internal class AreaItem
    {
        /// <summary>
        /// 交管区ID
        /// </summary>
        public long  AreaID { get; set; }  

        /// <summary>
        /// 几何点位
        /// </summary>
        public List<PointF> PointList { get; set; } = new List<PointF>();

        /// <summary>
        /// 状态
        /// </summary>
        public bool Disable { get; set; }

        /// <summary>
        /// 轮廓最大X值
        /// </summary>
        public int MaxX { get; set; }

        /// <summary>
        /// 轮廓最大Y值
        /// </summary>
        public int MaxY { get; set; }

        /// <summary>
        /// 轮廓最小X
        /// </summary>
        public int MinX { get; set; }


        /// <summary>
        /// 轮廓最小Y
        /// </summary>
        public int MinY { get; set; }
    }

    #endregion
}
